interface WebSocketMessage {
  type: 'MEASUREMENT';
  data: [number, number]; // [distance, angle]
}

type WebSocketCallback = (message: WebSocketMessage) => void;

export class WebSocketService {
  private ws: WebSocket | null = null;
  private callback: WebSocketCallback | null = null;
  private pendingCommand: string | null = null;

  connect(address: string = 'localhost:8080', onDataReceived: WebSocketCallback): Promise<void> {
    return new Promise((resolve, reject) => {
      this.callback = onDataReceived;
      const wsAddress = address || '192.168.64.129:8080';
      this.ws = new WebSocket(`ws://${wsAddress}`);

      this.ws.onopen = () => {
        console.log('WebSocket connected');
        if (this.pendingCommand) {
          this.ws?.send(this.pendingCommand);
          this.pendingCommand = null;
        }
        resolve();
      };

      this.ws.onmessage = (event) => {
        try {
          const message = JSON.parse(event.data);
          if (message.type === 'MEASUREMENT' && Array.isArray(message.data) && message.data.length === 2) {
            this.callback?.(message);
          }
        } catch (error) {
          console.error('Failed to parse WebSocket message:', error);
        }
      };

      this.ws.onerror = (error) => {
        console.error('WebSocket error:', error);
        reject(error);
      };

      this.ws.onclose = () => {
        console.log('WebSocket connection closed');
        this.ws = null;
      };
    });
  }

  private sendCommand(command: string) {
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(command);
    } else if (this.ws?.readyState === WebSocket.CONNECTING) {
      this.pendingCommand = command;
    } else {
      console.error('WebSocket is not connected');
    }
  }

  startDetection() {
    this.sendCommand(JSON.stringify({ command: 'ACTION' }));
  }

  stopDetection() {
    this.sendCommand(JSON.stringify({ command: 'STOP' }));
  }

  notifyExceededDistance(email: string, distance: number) {
    this.sendCommand(JSON.stringify({
      callThePolice: '1',
      email,
      distance: distance.toString()
    }));
  }

  disconnect() {
    if (this.ws) {
      this.ws.close();
      this.ws = null;
      this.callback = null;
      this.pendingCommand = null;
    }
  }
} 